<?php
/***
* @version $Id: class_hooks.php 336 2007-01-23 08:12:56Z flexiondotorg $
* @copyright (c) 2006 - 2007 Flexion.Org
*            (c) 2004 - 2005 Project Minerva
* @license   http://opensource.org/licenses/gpl-license.php GNU Public License
***/

if (!defined('IN_R3BORN'))
{
	die('Hacking attempt');
}

/***
* Basic Hooks class
* @author Chris Smith <chris@project-minerva.org>
***/

class Hooks
{
	/**
	* @access private
	* @var array Hooks and their callbacks
	*/
	var $hooks = array();

	/**
	* Constructor
	* @access public
	* @return void
	*/
    /*
	function hooks()
	{
		return;
	}
	*/

	/**
	* Bind a callback (with arguments) to a hook
	*
	* $hooks->bind('user_delete', 'update_newest_user');                    would bind the function update_newest_user() to 'user_delete'
	* $hooks->bind('user_delete', array('user_control', 'update_stats'));   would bind the method update_stats() from the class 'user_control' to 'user_delete'
	* $hooks->bind('hookname', array('&$object', 'method'));
           *
	* @access public
	* @param string $hook Name of the hook to bind to
	* @param callback $callback Callback to call when the hook is executed
	* @return void
	**/
	function bind($hook, $callback)
	{
		if (!is_callable($callback))
		{
			return;
		}
		else if (!isset($this->hooks[$hook]))
		{
			$this->hooks[$hook] = array();
		}

		if (func_num_args() > 2)
		{
			// We have additional arguments
			$args = array_slice(func_get_args(), 2);
		}
		else
		{
			$args = array();
		}

		$this->hooks[$hook][] = array(
			'callback'    => $callback,
			'args'        => $args,
		);
	}

	/**
	* Execute a hook
	*
	* $hooks->execute('user_delete', 'Delete me');      would execute the user_delete hook and pass the argument 'Delete Me'
	*
	* @access public
	* @param string $hook Name of the hook that should be execute
	* @return void
	**/
	function execute($hook)
	{
		if (!isset($this->hooks[$hook]))
		{
			return;
		}

		if (func_num_args() > 1)
		{
			// We have additional arguments
			$extra_args = array_slice(func_get_args(), 1);
		}
		else
		{
			$extra_args = array();
		}

		foreach (array_keys($this->hooks[$hook]) as $i)
		{
			$callback = $this->hooks[$hook][$i]['callback'];
			$args = array_merge($this->hooks[$hook][$i]['args'], $extra_args);
			call_user_func_array($callback, $args);
		}
	}
}

/***
* Get the hooks
*  - Optionally just get the compoent named in $needle rather than all components
*  - Optionally restrict the search to just the module name defined in $module_name
***/
function getHooks($needle = '', $module_name = '')
{
	global $root_path, $phpEx, $mvModules;

	$list = array();

	foreach ($mvModules as $name => $value)
	{
	    //If the search is limited to a particular module_name, skip any modules which do not match the module_name supplied.
		if ($module_name != '' && $module_name != $name)
		{
			continue;
		}

		if (getModuleStatus($name) == MODULE_ENABLED || getModuleStatus($name) == MODULE_DEFAULT)
		{
			$list[$name] = array();

			// Add each component which matches to the array
			foreach ($value['components'] as $file)
			{
				$component = substr($file, 0, strpos($file, '.' . $phpEx));

				if ($component == $needle || $needle == '')
				{
					$list[$name][] = $component;
				}
			}
			$list[$name] = array_unique($list[$name]);
		}
	}
	return $list;
}

/***
* Load all the hooks from a array list.
***/
function loadHooks($list)
{
	global $root_path, $phpEx, $hooks;

	foreach ($list as $modulename => $component)
	{
		$component_size = count($component);
		if ($component_size != 0)
		{
			for($i = 0; $i<$component_size; $i++)
			{
				include_once($root_path . 'modules/' . $modulename . '/components/' . $component[$i] . '.' . $phpEx);
			}
		}
	}
}

$hooks = new Hooks;

?>